﻿using System;
using System.Data;
using Cesave.Domain.Core;
using Cesave.Domain.PermisosModule.Entities;
using Cesave.Domain.PermisosModule.Resources;
using Cesave.Domain.PermisosModule.Contracts.Distritos;

namespace Cesave.Domain.PermisosModule.Contracts.DistritosPersonal
{
	/// <summary>
	/// 
	/// </summary>
	public class DistritoPersonalService
		: IDistritoPersonalService
	{
		#region Private properties

		/// <summary>
		/// 
		/// </summary>
		private readonly IDistritoPersonalRepository _distritoPersonalRepository;

		#endregion

		#region Constructor

		/// <summary>
		/// 
		/// </summary>
		/// <param name="distritoPersonalRepository"></param>
		public DistritoPersonalService(IDistritoPersonalRepository distritoPersonalRepository)
		{
			if (distritoPersonalRepository == null)
				throw new ArgumentNullException("distritoPersonalRepository", Messages.exception_DependenciesAreNotInitialized);
			_distritoPersonalRepository = distritoPersonalRepository;
		}

		#endregion

		#region IDistritoPersonalService Members

		/// <summary>
		/// 
		/// </summary>
		/// <param name="distritoGuid"></param>
		/// <param name="cicloGuid"></param>
		/// <returns></returns>
		public DistritoPersonal FindDistritoPersonalByDistritoAndCiclo(Guid distritoGuid, Guid cicloGuid)
		{
			if (distritoGuid == Guid.Empty)
				throw new InvalidOperationException("distritoGuid");
			if (cicloGuid == Guid.Empty)
				throw new InvalidOperationException("cicloGuid");
			DistritoPersonalByDistritoSpecification distritoPersonalByDistritoSpecification = new DistritoPersonalByDistritoSpecification(distritoGuid);
			DistritoPersonalByCicloSpecification distritoPersonalByCicloSpecification = new DistritoPersonalByCicloSpecification(cicloGuid);
			DistritoPersonal distritoPersonal;
			if (null == (distritoPersonal = _distritoPersonalRepository.FindDistritoPersonalByDistritoAndCicloSpecification(distritoPersonalByDistritoSpecification, distritoPersonalByCicloSpecification)))
			{
				distritoPersonal = new DistritoPersonal
				{
					PersonalGuid = Guid.NewGuid(),
					PersonalId = 0,
					CicloGuid = cicloGuid,
					CicloId = 0,
					DistritoGuid = distritoGuid,
					DistritoId = 0,
					Status = true,
					Jefe = string.Empty,
				};
				IUnitOfWork unitOfWork = _distritoPersonalRepository.StoreContext;
				_distritoPersonalRepository.Add(distritoPersonal);
				try
				{
					unitOfWork.Commit();
				}
				catch (OptimisticConcurrencyException ex)
				{
					unitOfWork.RollbackChanges();
					unitOfWork.CommitAndRefreshChanges();
					throw ex;
				}
			}
			return distritoPersonal;
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="distritoPersonal"></param>
		public void AddDistritoPersonal(DistritoPersonal distritoPersonal)
		{
			if (distritoPersonal == null)
				throw new ArgumentNullException("distritoPersonal", Messages.exception_InvalidArgument);
			IUnitOfWork unitOfWork = _distritoPersonalRepository.StoreContext;
			_distritoPersonalRepository.Add(distritoPersonal);
			try
			{
				unitOfWork.Commit();
			}
			catch (OptimisticConcurrencyException)
			{
				unitOfWork.RollbackChanges();
				unitOfWork.CommitAndRefreshChanges();
			}
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="distritoPersonal"></param>
		public void ChangeDistritoPersonal(DistritoPersonal distritoPersonal)
		{
			if (distritoPersonal == null)
				throw new ArgumentNullException("distritoPersonal", Messages.exception_InvalidArgument);
			IUnitOfWork unitOfWork = _distritoPersonalRepository.StoreContext;
			_distritoPersonalRepository.Modify(distritoPersonal);
			try
			{
				unitOfWork.Commit();
			}
			catch (OptimisticConcurrencyException)
			{
				unitOfWork.RollbackChanges();
				unitOfWork.CommitAndRefreshChanges();
			}
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="distritoPersonal"></param>
		public void DeleteDistritoPersonal(DistritoPersonal distritoPersonal)
		{
			if (distritoPersonal == null)
				throw new ArgumentNullException("distritoPersonal", Messages.exception_InvalidArgument);
			IUnitOfWork unitOfWork = _distritoPersonalRepository.StoreContext;
			DistritoPersonalByDistritoSpecification distritoPersonalSpecification = new DistritoPersonalByDistritoSpecification(distritoPersonal.DistritoGuid);
			var personales = _distritoPersonalRepository.GetBySpec(distritoPersonalSpecification);
			foreach (DistritoPersonal personal in personales)
			{
				_distritoPersonalRepository.Remove(personal);
			}
			try
			{
				unitOfWork.Commit();
			}
			catch (OptimisticConcurrencyException)
			{
				unitOfWork.RollbackChanges();
				unitOfWork.CommitAndRefreshChanges();
			}
		}

		#endregion

		#region IDisposable Members

		public void Dispose()
		{
			if (_distritoPersonalRepository != null &&
				_distritoPersonalRepository.StoreContext != null)
				_distritoPersonalRepository.StoreContext.Dispose();
		}

		#endregion
	}
}
